const loginService = require("../login/login");
const server = require('../login/server');
const interfaces = require('../api/interfaces');
const textUtil = require('../utils/textUtil');
const accountList = require("../data/account.json");
const noticeEventType = require('../data/noticeEventType.json');

class App {
    async run() {
        for (let item of accountList) {
            this.user = item;
            if (!this.user.enable) {
                continue;
            }

            let loginState = false;

            if (this.user.game.serverType === 1) {
                loginState = await this.loginH5();
            } else {
                loginState = await this.login();
            }

            if (!loginState) {
                continue;
            }

            await this.getPlayerData();

            await this.endAFK();

            await this.sports();

            if (this.user.config.gold.enable) {
                await this.gold();
            }

            if (this.user.config.special.enable) {
                await this.special();
            }

            if (this.user.config.entrust.enable && this.user.game.other.dayData.doneTask['6'] !== 14) {
                await this.entrust();
            }

            if (this.user.config.copy.enable && this.user.game.other.dayData.doneTask['2'] !== 6) {
                await this.copy();
            }

            //await this.ufoCatcher();

            if (this.user.config.notice.enable) {
                await this.notice();
            }

            if (this.user.config.circleTask.enable && this.user.game.other.dayData.doneTask['3'] !== 100) {
                this.circleTask(this.user);
            }
        }
    }

    async loginH5() {
        const method = '登录';
        const l = new interfaces.Login(this.user);
        try {
            //登录
            const cookie = await loginService.h5.login_4399(this.user.username, this.user.password);

            //授权
            const retData = await loginService.h5.auth_4399(cookie);

            //获取checkObj信息
            const checkObj = await loginService.h5.getUserData_4399(retData.uid, retData.access_token, retData.cookie);
            checkObj.device = 'pc';
            this.user.game.checkObj = checkObj;
            this.user.game.data.userAccount = checkObj.userId;

            //获取区服信息
            const serverInfo = await server.getServerData(1, this.user.game.serverCode);
            this.user.game.reqUrl = serverInfo.reqUrl;
            this.user.game.quickLoginUrl = serverInfo.quickLoginUrl;
            this.user.game.serverName = serverInfo.serverName;

            //获取roleID loginFlag信息
            const quickData = await l.quickLogin({account: checkObj.userId, pwd: '123456', checkObj: checkObj, channel: '4399', flag: 1, macAdress: '', platform: 5});
            this.user.game.data.roleID = quickData.roleID;
            this.user.game.data.loginFlag = quickData.loginFlag;
            this.user.game.data.userAccount = quickData.account;

            this.outLog(true, method, this.user.username, `游戏区服: ${serverInfo.serverName}`);
            return true;
        } catch (e) {
            this.outLog(false, method, this.user.username, `游戏区服: ${this.user.game.serverName}[${this.user.game.serverCode}] Err: ${e}`);
        }
        return false;
    }

    async login() {
        const method = '登录';
        const l = new interfaces.Login(this.user);
        try {
            //登录
            const info = await loginService.official.login(this.user.username, this.user.password);
            this.user.game.data.userAccount = info.loginid;

            //获取区服信息
            const serverInfo = await server.getServerData(2, this.user.game.serverCode);
            this.user.game.reqUrl = serverInfo.reqUrl;
            this.user.game.quickLoginUrl = serverInfo.quickLoginUrl;
            this.user.game.serverName = serverInfo.serverName;

            //获取roleID loginFlag信息
            const quickData = await l.quickLogin({account: info.loginid, pwd: '123456', checkObj: {app: 'tfy-xf', sdk: 'meple100221', uin: info.loginid, sess: info.token, newPack: 1}, channel: 'meple100221', flag: 1, macAdress: '541007DCAFC5FE327873D1863EF27164D07CC3C1', platform: 0});
            this.user.game.data.roleID = quickData.roleID;
            this.user.game.data.loginFlag = quickData.loginFlag;
            this.user.game.data.userAccount = quickData.account;

            this.outLog(true, method, this.user.username, `游戏区服: ${serverInfo.serverName}`);
            return true;
        } catch (e) {
            this.outLog(false, method, this.user.username, `游戏区服: ${this.user.game.serverName}[${this.user.game.serverCode}] Err: ${e}`);
        }
        return false;
    }

    async getPlayerData() {
        const method = '获取玩家数据';
        const p = new interfaces.Player(this.user);
        try {
            //获取游戏数据
            const loadGameData = await p.getLoadGameData();
            this.user.game.data.inGameTime = loadGameData.baseValueAy[36];
            this.user.game.player = loadGameData.baseValueAy;
            this.user.game.other = loadGameData;

            //获取福缘
            const luckyData = await p.getLucky();
            this.user.game.lucky = luckyData.Luck;

            this.outLog(true, method, this.user.username, `福缘: ${luckyData.Luck}`);
        } catch (e) {
            this.outLog(false, method, this.user.username, `Err: ${e}`);
        }
    }

    async endAFK() {
        const method = '结束挂机';
        const p = new interfaces.Player(this.user);
        try {
            //获取挂机数据
            const hookObj = this.user.game.other.OnhookObj;

            if (hookObj.flag === 1 && hookObj.beginTime > 0) {
                switch (hookObj.operate) {
                    case 6:
                        const hitPileRes = await p.endHitPile();
                        this.outLog(true, method, this.user.username, `打桩 奖励: 潜能x${hitPileRes.potential} 经验x${hitPileRes.exp} 奇遇: ${hitPileRes.specialAny.length===0?'无':textUtil.getHitPileEventName(hitPileRes.specialAny)}`);
                        break;
                }
            }
        } catch (e) {
            this.outLog(false, method, this.user.username, `Err: ${e}`);
        }
    }

    async copy() {
        const method = '副本';
        const c = new interfaces.Copy(this.user);
        try {
            for (let i = 0; i < 2; i++) {
                const id = i + 1;
                const data = await c.getData(id);
                const arrData = data[data.p].copyArr;

                if (data[1] > 0) {
                    const buyRes = await c.buyCount(id, data[1]);
                    this.outLog(buyRes[buyRes.p].eRet===1, method, this.user.username, `购买次数 副本名称: ${c.getCopyName(id) + buyRes[buyRes.p].eRet===1?'成功':'失败'}`);
                }

                if (this.user.game.isVip) { // 扫荡
                    const sweepRes = await c.sweep(id, this.user.config.copy[id].state, arrData[0]);
                    const rewardArray = sweepRes[sweepRes.p].rewardArray;
                    this.outLog(true, method, this.user.username, `扫荡 副本名称: ${c.getCopyName(id)} 奖励: ${textUtil.getItemName(rewardArray)}`);
                    this.updateItemObj(sweepRes[sweepRes.p].note.ivch);
                } else { // 手动挑战
                    for (let j = 0; j < arrData[0]; j++) {
                        const enter = await c.enter(id, this.user.config.copy[id].state);
                        if (enter) {
                            const res = await c.leave(id);
                            const rewardArray = res[res.p].rewardArray;
                            this.outLog(true, method, this.user.username, `完成 副本名称: ${c.getCopyName(id)} 奖励: ${textUtil.getItemName(rewardArray)}`);
                            this.updateItemObj(res[res.p].note.ivch);
                        } else {
                            this.outLog(false, method, this.user.username, `副本名称: ${c.getCopyName(id)} 进入失败`);
                        }
                    }
                }
            }
        } catch (e) {
            this.outLog(false, method, this.user.username, `Err: ${e}`);
        }
    }

    async notice() {
        const method = '公告牌';
        const n = new interfaces.Notice(this.user);
        try {
            const noticeEvent = await n.getNoticeEvent();
            this.outLog(true, method, this.user.username, `事件 类型: ${noticeEventType[noticeEvent.type]}[${noticeEvent.type}]`);

            if (this.user.game.other.dayData.doneTask['1'] === 14) {
                return;
            }

            for (let i = 0; i < noticeEvent.count; i++) {
                const refreshEvent = await n.refreshNotice(0);
                const eventData = refreshEvent[refreshEvent.p];
                let res = null;
                let rewardArray = {};

                if (eventData.eventType == null) {
                    continue;
                }

                switch (eventData.eventType) {
                    case 1: //宝箱
                        res = await n.getNoticeAward(1000, eventData.eventID);
                        rewardArray = res[res.p].rewardArray;
                        this.outLog(true, method, this.user.username, `宝箱 奖励: ${textUtil.getItemName(rewardArray)}`);
                        break;
                    case 3: //押镖
                        res = await n.getNoticeAward(1008, eventData.eventID);
                        rewardArray = res[res.p].rewardArray;
                        this.outLog(true, method, this.user.username, `押镖 奖励: ${textUtil.getItemName(rewardArray)}`);
                        break;
                    case 5: //四大恶人
                        res = await n.getVillainAward(eventData.eventID);
                        rewardArray = res[res.p].rewardArray;
                        this.outLog(true, method, this.user.username, `四大恶人 奖励: ${textUtil.getItemName(rewardArray)}`);
                        break;
                    case 6: //奇人异事
                        res = await n.getRandEventAward(0, 1, 0);
                        rewardArray = res[res.p].rewardArray;
                        this.outLog(true, method, this.user.username, `奇人异事 奖励: ${textUtil.getItemName(rewardArray)}`);
                        break;
                }
            }
        } catch (e) {
            this.outLog(true, method, this.user.username, `Err: ${e}`);
        }
    }

    async entrust() {
        const method = '委托任务';
        const e = new interfaces.Entrust(this.user);
        try {
            const entrustTaskRes = await e.getEntrustTaskList();
            const taskList = entrustTaskRes[entrustTaskRes.p].taskArr;
            let res = null;
            let rewardArray = {};
            let state = false;
            const tokenItemID = 4540;
            const tokenPackageItemID = 4763;
            let startTokenCount = this.getItemNumber(tokenItemID);
            for (const v of taskList) {
                if (v.state === 4) {
                    res = await e.getEntrustReward(v.id);
                    rewardArray = res[res.p].rewardObj;
                    this.outLog(true, method, this.user.username, `领取 奖励: ${textUtil.getItemName(rewardArray)}`);
                    continue;
                }

                if (v.state !== 1 && v.state !== 2) {
                    continue;
                }

                if (v.type === 1) {
                    this.outLog(await e.entrustTask(v.id), method, this.user.username, `打扫战场`);
                    continue;
                }

                let refreshRes = null;
                let refreshData = {};
                let level = v.lv;
                let entrustTaskState = false;

                //购买委托令体验包
                if ((this.getItemNumber(tokenItemID) == null || this.getItemNumber(tokenItemID) === 0) && this.user.config.entrust.buyTokenPackage.enable) {
                    //购买
                    if (await this.buyTokenPackage()) {
                        startTokenCount = this.getItemNumber(tokenItemID);
                    }
                }

                if (this.user.config.entrust.type === 2 && (this.getItemNumber(tokenItemID) == null || this.getItemNumber(tokenItemID) === 0)) {
                    this.outLog(false, method, this.user.username, `高级委托令不足`);
                    return;
                }

                //刷星级
                while (level !== this.user.config.entrust.level) {
                    if (this.getItemNumber(tokenItemID) == null || this.getItemNumber(tokenItemID) === 0) {
                        if (await this.buyTokenPackage()) {
                            startTokenCount = startTokenCount === 0 ? this.getItemNumber(tokenItemID) : startTokenCount + this.getItemNumber(tokenItemID);
                        } else {
                            this.outLog(false, method, this.user.username, `高级委托令不足停止刷新`);
                            return;
                        }
                    }

                    refreshRes = await e.refreshEntrustTask([v.id], this.user.config.entrust.type);
                    refreshData = refreshRes[refreshRes.p];
                    level = refreshData.taskObj[v.id].lv;

                    this.updateOneItemObj(tokenItemID, this.getItemNumber(tokenItemID) - 1);
                }

                //委托
                while (!entrustTaskState) {
                    const type = refreshRes != null ? refreshData.taskObj[v.id].t : v.type;

                    //拜访
                    if (this.user.config.entrust.visit && type === 2) {
                        let p = refreshRes != null ? refreshData.taskObj[v.id].c : v.param;

                        if (this.getItemNumber(p[1]) != null && this.getItemNumber(p[1]) >= p[2]) {
                            if (await e.entrustTask(v.id)) {
                                this.outLog(true, method, this.user.username, `拜访 消耗: ${textUtil.getOneItemName(p[1])}x${p[2]}`);
                                this.updateOneItemObj(p[1], this.getItemNumber(p[2]) - 1);
                                entrustTaskState = true;
                                break;
                            } else {
                                this.outLog(false, method, this.user.username, `拜访`);
                            }
                        }
                    }

                    //教训
                    if (this.user.config.entrust.punishment && type === 3) {
                        let p = refreshRes != null ? refreshData.taskObj[v.id].c : v.param;
                        // 判断技能、等级
                        if (this.getSkillInfo(p[1]) != null && this.getSkillInfo(p[1])[0] > p[2]) {
                            if (await e.entrustTask(v.id)) {
                                this.outLog(true, method, this.user.username, `教训 Npc: ${textUtil.getNpcName(p[0])}[${p[0]}] 武学: ${textUtil.getSkillName(p[1])}[${p[1]}] 等级: ${p[2]}`);
                                entrustTaskState = true;
                                break;
                            } else {
                                this.outLog(false, method, this.user.username, `教训`);
                            }
                        }
                    }

                    //打探
                    if (this.user.config.entrust.inquire && type === 4) {
                        let p = refreshRes != null ? refreshData.taskObj[v.id].c : v.param;
                        if (await e.entrustTask(v.id)) {
                            this.outLog(true, method, this.user.username, `打探 mapID: ${p[0]} 消耗: 银两x${p[1]}`);
                            entrustTaskState = true;
                            break;
                        } else {
                            this.outLog(false, method, this.user.username, `打探`);
                        }
                    }

                    if (this.getItemNumber(tokenItemID) === 0) {
                        if (await this.buyTokenPackage()) {
                            startTokenCount = startTokenCount === 0 ? this.getItemNumber(tokenItemID) : startTokenCount + this.getItemNumber(tokenItemID);
                        } else {
                            this.outLog(false, method, this.user.username, `高级委托令不足停止刷新`);
                            return;
                        }
                    }
                    refreshRes = await e.refreshEntrustTask([v.id], this.user.config.entrust.type);
                    refreshData = refreshRes[refreshRes.p];

                    this.updateOneItemObj(tokenItemID, this.getItemNumber(tokenItemID) - 1);
                }
                state = true;
            }

            if (state) {
                this.outLog(true, method, this.user.username, `高级委托令剩余: ${this.getItemNumber(tokenItemID)} 共计消耗: ${startTokenCount - this.getItemNumber(tokenItemID)} 个`);
            }
        } catch (e) {
            this.outLog(false, method, this.user.username, `Err: ${e}`);
        }
    }

    async buyTokenPackage() {
        const tokenPackageItemID = 4763;
        const buyRes = await this.buyMarkerItem(tokenPackageItemID, this.user.config.entrust.buyTokenPackage.number);
        if (buyRes) {
            return await this.useItem(tokenPackageItemID, this.getItemNumber(tokenPackageItemID))
        }
        return false;
    }

    async gold() {
        const method = '金条';
        const g = new interfaces.Gold(this.user);
        try {
            for (let i = 0; i < 2; i++) {
                const type = i + 1;
                const aData = await g.getAdvertisementData(type);
                for (let j = 0; j < aData.advertisementNum; j++) {
                    const aRewardData = await g.getAdvertisementReward(type);
                    if (aRewardData.eRet === 1) {
                        this.updateGold(this.getCurredGold() + 2);
                    }
                    this.outLog(true, method, this.user.username, `奖励: ${textUtil.getItemName(aRewardData.awardArr)}`);
                    if (type === 1 && aData.advertisementNum > 1) {
                        await this.sleep(15000);
                    }
                }
            }
        } catch (e) {
            this.outLog(false, method, this.user.username, `Err: ${e}`);
        }
    }

    async circleTask(user) {
        const method = '环任务';
        const c = new interfaces.CircleTask(user);
        try {
            const taskIDArray = [1000010, 1000020, 1000030]; //1000010,
            let exp = 0;
            let gameCoin = 0;
            let skillExp = 0;
            let count = 0;
            for (let i = 0; i < taskIDArray.length; i++) {
                for (let j = 0; j < user.config.circleTask[i + 1]; j++) {
                    const aRes = await c.accept(taskIDArray[i]);
                    const bRes = await c.complete(taskIDArray[i], aRes[aRes.p].retData);
                    gameCoin += bRes[bRes.p].rewardArray[4001] != null ? bRes[bRes.p].rewardArray[4001] : 0;
                    exp += bRes[bRes.p].rewardArray[4002] != null ? bRes[bRes.p].rewardArray[4002] : 0;
                    skillExp += bRes[bRes.p].rewardArray[4003] != null ? bRes[bRes.p].rewardArray[4003] : 0;

                    if (bRes.error !== 0 || bRes[bRes.p].eRet !== 1) {
                        break;
                    }

                    this.outLog(true, method, user.username, `奖励: ${textUtil.getItemName(bRes[bRes.p].rewardArray)}`);

                    count++;

                    if (i + 1 === taskIDArray.length && j + 1 === user.config.circleTask[i + 1]) {
                        break;
                    }

                    //等待15秒后开始下一轮
                    await this.sleep(15000);
                }
            }
            this.outLog(true, method, user.username, `完成${count}次 总计奖励: ${textUtil.getOneItemName(4001)}x${gameCoin} ${textUtil.getOneItemName(4002)}x${exp} ${textUtil.getOneItemName(4003)}x${skillExp}`);
        } catch (e) {
            this.outLog(false, method, user.username, `Err: ${e}`);
        }
    }

    async special() {
        const method = '特殊检测';
        const s = new interfaces.Special(this.user);
        try {
            const title = {1: '未知', 2: '危虎山', 3: '老乞丐'};
            const list = this.user.config.special.list;
            for (let i = 0; i < list.length; i++) {
                const aRes = await s.check(list[i]);
                if (aRes[aRes.p].eRet === 1) {
                    const bRes = await s.getReward(list[i]);
                    this.outLog(true, method, this.user.username, `触发 ${title[list[i]]} 奖励: ${textUtil.getItemName(bRes[bRes.p].rewardArray)}`);
                } else {
                    this.outLog(true, method, this.user.username, `未触发 ${title[list[i]]}`);
                }
            }
        } catch (e) {
            this.outLog(false, method, this.user.username, `Err: ${e}`);
        }
    }

    async ufoCatcher() {
        const method = '娃娃机';
        const u = new interfaces.festivity.UFOCatcher(this.user);
        try {
            const gameCoinPackage = this.getItemNumber('8143')??0;
            if (gameCoinPackage > 0) {
                await this.useItem(8143, gameCoinPackage);
            }
            const items = [this.getItemNumber('8119')??0,this.getItemNumber('8120')??0,this.getItemNumber('8117')??0];
            this.outLog(true, method, this.user.username, `道具数量: ${textUtil.getOneItemName(8119)}x${this.getItemNumber(8119)} ${textUtil.getOneItemName(8120)}x${this.getItemNumber(8120)} ${textUtil.getOneItemName(8117)}x${this.getItemNumber(8117)}`);
            let ufoData = await u.getCurrentData();
            let rewardPool = ufoData[ufoData.p].rewardPool;
            let freeRefresh = ufoData[ufoData.p].freeRefreshTimes === 1;
            let signId = ufoData[ufoData.p].signId;
            let packageArray = {};
            let getRewardData = {};
            let total = 0;

            for (let i = 0; i < items.length; i++) {
                for (let j = 0; j < items[i]; j++) {
                    total = 0;
                    packageArray = {};
                    switch (i) {
                        case 0: //穿透抓钩
                            if (freeRefresh && (rewardPool['5'] === 0 || rewardPool['4'] === 0)) {
                                let refreshData = await u.freeRefresh();
                                if (refreshData[refreshData.p].eRet !== 1) {
                                    break;
                                }
                                this.outLog(true, method, this.user.username, `刷新奖励 奖励: ${JSON.stringify(refreshData[refreshData.p].rewardPool)}`);
                                rewardPool = refreshData[refreshData.p].rewardPool;
                                signId = refreshData[refreshData.p].signId;
                                freeRefresh = refreshData[refreshData.p].freeRefreshTimes === 1;
                            }
                            if ((rewardPool['5'] + rewardPool['4']) > 5) {
                                packageArray = {'4': (rewardPool['5']===2?rewardPool['4']-1:rewardPool['4']), '5': rewardPool['5']};
                            } else if ((rewardPool['5'] + rewardPool['4']) === 5) {
                                packageArray = {'4': rewardPool['4'], '5': rewardPool['5']};
                            } else {
                                if (rewardPool['5'] > 0) {
                                    packageArray['5'] = rewardPool['5'];
                                    total += packageArray['5'];
                                }
                                if (rewardPool['4'] > 0) {
                                    packageArray['4'] = rewardPool['4'];
                                    total += packageArray['4'];
                                }
                                if (total < 5 && rewardPool['3'] > 0) {
                                    packageArray['3'] = rewardPool['3']>(Math.abs(total-5))?Math.abs(total-5):rewardPool['3'];
                                    total += packageArray['3'];
                                }
                                if (total < 5 && rewardPool['2'] > 0) {
                                    packageArray['2'] = rewardPool['2']>(Math.abs(total-5))?Math.abs(total-5):rewardPool['2'];
                                    total += packageArray['2'];
                                }
                                if (total < 5 && rewardPool['1'] > 0) {
                                    packageArray['1'] = rewardPool['1']>(Math.abs(total-5))?Math.abs(total-5):rewardPool['1'];
                                    total += packageArray['1'];
                                }
                                if (total < 5) {
                                    //次数不足则跳出
                                    break;
                                }
                            }
                            getRewardData = await u.getReward(packageArray, 8119, signId);
                            if (getRewardData[getRewardData.p].eRet === 1) {
                                this.updateItemObj(getRewardData[getRewardData.p].note.ivch);
                                rewardPool = getRewardData[getRewardData.p].rewardPool;
                                signId = getRewardData[getRewardData.p].signId;
                                this.outLog(true, method, this.user.username, `消耗: ${textUtil.getOneItemName(8119)}x1 奖励: ${textUtil.getItemName(getRewardData[getRewardData.p].rewardArray)}`);
                            } else {
                                this.outLog(true, method, this.user.username, `使用穿透抓钩道具抓取失败: req: ${JSON.stringify(packageArray)} res: ${JSON.stringify(getRewardData)}`);
                            }
                            break;
                        case 1: //引力抓钩
                            if (freeRefresh && (rewardPool['5'] === 0 || rewardPool['4'] === 0)) {
                                let refreshData = await u.freeRefresh();
                                if (refreshData[refreshData.p].eRet !== 1) {
                                    break;
                                }
                                this.outLog(true, method, this.user.username, `刷新奖励 奖励: ${JSON.stringify(refreshData[refreshData.p].rewardPool)}`);
                                rewardPool = refreshData[refreshData.p].rewardPool;
                                signId = refreshData[refreshData.p].signId;
                                freeRefresh = refreshData[refreshData.p].freeRefreshTimes === 1;
                            }
                            if ((rewardPool['5'] + rewardPool['4']) > 3) {
                                if (rewardPool['5'] !== 0) {
                                    packageArray['5'] = rewardPool['5'];
                                    total += packageArray['5'];
                                }
                                if (rewardPool['4'] !== 0) {
                                    packageArray['4'] = total===1?2:1;
                                    total += packageArray['4'];
                                }
                            } else if ((rewardPool['5'] + rewardPool['4']) === 3) {
                                if (rewardPool['5'] !== 0) {
                                    packageArray['5'] = rewardPool['5'];
                                    total += packageArray['5'];
                                }
                                if (rewardPool['4'] !== 0) {
                                    packageArray['4'] = total===1?2:1;
                                    total += packageArray['4'];
                                }
                            } else {
                                if (rewardPool['5'] > 0) {
                                    packageArray['5'] = rewardPool['5'];
                                    total += packageArray['5'];
                                }
                                if (rewardPool['4'] > 0) {
                                    packageArray['4'] = rewardPool['4'];
                                    total += packageArray['4'];
                                }
                                if (total < 3 && rewardPool['3'] > 0) {
                                    packageArray['3'] = rewardPool['3']>(Math.abs(total-3))?Math.abs(total-3):rewardPool['3'];
                                    total += packageArray['3'];
                                }
                                if (total < 3 && rewardPool['2'] > 0) {
                                    packageArray['2'] = rewardPool['2']>(Math.abs(total-3))?Math.abs(total-3):rewardPool['2'];
                                    total += packageArray['2'];
                                }
                                if (total < 3 && rewardPool['1'] > 0) {
                                    packageArray['1'] = rewardPool['1']>(Math.abs(total-3))?Math.abs(total-3):rewardPool['1'];
                                    total += packageArray['1'];
                                }
                                if (total < 3) {
                                    //次数不足则跳出
                                    break;
                                }
                            }
                            getRewardData = await u.getReward(packageArray, 8120, signId);
                            if (getRewardData[getRewardData.p].eRet === 1) {
                                this.updateItemObj(getRewardData[getRewardData.p].note.ivch);
                                rewardPool = getRewardData[getRewardData.p].rewardPool;
                                signId = getRewardData[getRewardData.p].signId;
                                this.outLog(true, method, this.user.username, `消耗: ${textUtil.getOneItemName(8120)}x1 奖励: ${textUtil.getItemName(getRewardData[getRewardData.p].rewardArray)}`);
                            } else {
                                this.outLog(true, method, this.user.username, `使用引力抓钩道具抓取失败: req: ${JSON.stringify(packageArray)} res: ${JSON.stringify(getRewardData)}`);
                            }
                            break;
                        case 2: //游戏币
                            if (freeRefresh && (rewardPool['5'] === 0 || rewardPool['4'] === 0)) {
                                let refreshData = await u.freeRefresh();
                                if (refreshData[refreshData.p].eRet !== 1) {
                                    break;
                                }
                                this.outLog(true, method, this.user.username, `刷新奖励 奖励: ${JSON.stringify(refreshData[refreshData.p].rewardPool)}`);
                                rewardPool = refreshData[refreshData.p].rewardPool;
                                signId = refreshData[refreshData.p].signId;
                                freeRefresh = refreshData[refreshData.p].freeRefreshTimes === 1;
                            }
                            if (rewardPool['5'] > 0) {
                                packageArray['5'] = 1;
                                total++;
                            }
                            if (total == 0 && rewardPool['4'] > 0) {
                                packageArray['4'] = 1;
                                total++;
                            }
                            if (total == 0 && rewardPool['3'] > 0) {
                                packageArray['3'] = 1;
                                total++;
                            }
                            if (total == 0 && rewardPool['2'] > 0) {
                                packageArray['2'] = 1;
                                total++;
                            }
                            if (total == 0 && rewardPool['1'] > 0) {
                                packageArray['1'] = 1;
                                total++;
                            }
                            if (total == 0) {
                                //次数不足则跳出
                                break;
                            }
                            getRewardData = await u.getReward(packageArray, 8117, signId);
                            if (getRewardData[getRewardData.p].eRet === 1) {
                                this.updateItemObj(getRewardData[getRewardData.p].note.ivch);
                                rewardPool = getRewardData[getRewardData.p].rewardPool;
                                signId = getRewardData[getRewardData.p].signId;
                                this.outLog(true, method, this.user.username, `消耗: ${textUtil.getOneItemName(8117)}x1 奖励: ${textUtil.getItemName(getRewardData[getRewardData.p].rewardArray)}`);
                            } else {
                                this.outLog(true, method, this.user.username, `使用游戏币道具抓取失败: req: ${JSON.stringify(packageArray)} res: ${JSON.stringify(getRewardData)}`);
                            }
                            break;
                    }
                }
            }

        } catch (e) {
            this.outLog(false, method, this.user.username, `Err: ${e}`);
        }
    }

    async sports() {
        const method = '竞技场';
        const s = new interfaces.Sports(this.user);
        try {
            let res = await s.getReward();
            let status = res.resultCode === 200 && res[res.p].eRet === 1;
            this.outLog(status, method, this.user.username,
                status ? `宝箱奖励: ${res[res.p].rewardArray != null ? textUtil.getItemName(res[res.p].rewardArray):"无"}` : `宝箱领取失败: ${JSON.stringify(res)}`
            );
        } catch (e) {
            this.outLog(false, method, this.user.username, `Err: ${e}`);
        }
    }

    /**
     * 购买商城物品
     * @param itemID 物品ID
     * @param number 购买数量
     * @returns {Promise<boolean>}
     */
    async buyMarkerItem(itemID, number) {
        const method = "商城购买";
        const s = new interfaces.Shopping(this.user);
        try {
            const marketListRes = await s.getMarketList();
            const list = marketListRes[marketListRes.p].market;

            for (const v in list) {
                if (list[v][4][0] !== itemID) {
                    continue;
                }

                const canBuyMaxQuantity = list[v][6] !== 0 ? list[v][6] - list[v][8] : 999999;
                const buyNumber = canBuyMaxQuantity >= number ? number : canBuyMaxQuantity;

                if (this.user.game.other.curGold < (buyNumber * list[v][5])) {
                    this.outLog(false, method, this.user.username, `物品: ${textUtil.getOneItemName(itemID)}x${buyNumber} 缺少金条: ${buyNumber * list[v][5]}`);
                    return false;
                }

                const buyRes = await s.buyMarketItem(v, buyNumber);
                if (buyRes.eRet === 1) {
                    this.outLog(true, method, this.user.username, `物品: ${textUtil.getOneItemName(itemID)}x${buyNumber}`);

                    //更新物品对象
                    this.updateItemObj(buyRes.note.ivch);

                    //更新金条
                    this.updateGold(buyRes.userGold);

                    return true;
                } else {
                    this.outLog(false, method, this.user.username, `物品: ${textUtil.getOneItemName(itemID)}x${buyNumber} 购买失败`);
                    return false;
                }
            }
            this.outLog(false, method, this.user.username, `物品: ${textUtil.getOneItemName(itemID)} 不存在`);
        } catch (e) {
            this.outLog(false, method, this.user.username, `Err: ${e}`);
        }
        return false;
    }

    /**
     * 使用物品
     * @param itemID 物品ID
     * @param number 使用数量
     * @returns {Promise<boolean>}
     */
    async useItem(itemID, number) {
        const method = "使用物品";
        const p = new interfaces.Player(this.user);
        try {
            //获取物品数量
            const itemNumber = this.getItemNumber(itemID);

            //物品数量小于使用数量则失败(false)
            if (itemNumber == null || itemNumber < number) {
                this.outLog(false, method, this.user.username, `物品: ${textUtil.getOneItemName(itemID)}x${number}[${itemID}] 数量不足`);
                return false;
            }

            const useRes = await p.useItem(itemID, number, {});
            const useData = useRes[useRes.p];
            if (useRes[useRes.p].eRet === 1) {
                this.outLog(true, method, this.user.username, `物品: ${textUtil.getOneItemName(itemID)}x${number}[${itemID}] 奖励: ${useData.rewardArray.length===0?'无':textUtil.getItemName(useData.rewardArray)}`);
                //更新物品对象
                this.updateItemObj(useData.note.ivch);
                return true;
            }
            this.outLog(false, method, this.user.username, `物品: ${textUtil.getOneItemName(itemID)}x${number}[${itemID}] 失败`);
        } catch (e) {
            this.outLog(false, method, this.user.username, `物品: ${textUtil.getOneItemName(itemID)}x${number}[${itemID}] Err: ${e}`);
        }
        return false;
    }

    /**
     * 更新物品对象
     * @param arr: {itemID: number}
     */
    updateItemObj(arr) {
        for (const k in arr) {
            this.user.game.other.itemObj[k] = arr[k];
        }
    }

    /**
     * 更新单个物品对象
     * @param id 物品id
     * @param number 数量
     */
    updateOneItemObj(id, number) {
        this.user.game.other.itemObj[id] = number;
    }

    /**
     * 更新金条数量
     * @param number 新数量
     */
    updateGold(number) {
        this.user.game.other.curGold = number;
    }

    getCurredGold() {
        return this.user.game.other.curGold;
    }

    /**
     * 获取物品数量
     * @param itemID 物品ID
     * @returns {*}
     */
    getItemNumber(itemID) {
        return this.user.game.other.itemObj[itemID]??0;
    }

    /**
     * 获取技能信息
     * @param skillID 技能ID
     * @returns {*}
     */
    getSkillInfo(skillID) {
        return this.user.game.other.skillMap[skillID];
    }

    outLog(state, method, username, other = '') {
        console.log(`[${state?'+':'-'}] ${method} [${username}] ${other}`);
    }

    sleep(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }
}

module.exports = App;